package se.jayway.opengl.tutorial;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

public class Square {
    final boolean hasColor;
    final boolean hasTexCoords;
    final int vertexSize;
    final IntBuffer vertices;
    final int[] tmpBuffer;
    final ShortBuffer indices;   
    int width, height;
    
	// Our vertices.
//	private float vertices[] = {
//		      -1.0f,  1.0f, 0.0f,  // 0, Top Left
//		      -1.0f, -1.0f, 0.0f,  // 1, Bottom Left
//		       1.0f, -1.0f, 0.0f,  // 2, Bottom Right
//		       1.0f,  1.0f, 0.0f,  // 3, Top Right
//		};
//	private float vertices[] = { -0.5f, -0.5f, -3, 1, 0, 0, 1,
//            0.5f, -0.5f, -3, 1, 0, 0, 1,
//            0.0f,  0.5f, -3, 1, 0, 0, 1,
//            
//            0.0f,  -0.5f, -5, 0, 1, 0, 1,
//            1.0f,  -0.5f, -5, 0, 1, 0, 1,
//            0.5f,  0.5f, -5, 0, 1, 0, 1};
	
	// The order we like to connect them.
//	private short[] indices = { 0, 1, 2, 0, 2, 3 };
//	private float vertices2[] = {
//			-0.5f,  0.5f, -0.9f,  // 0, Top Left
//			-0.5f, -0.5f, -0.9f,  // 1, Bottom Left
//			0.5f, -0.5f, -0.9f,  // 2, Bottom Right
//			0.5f,  0.5f, -0.9f,  // 3, Top Right
//	};
//	
//	// The order we like to connect them.
//	private short[] indices2 = { 0, 1, 2, 0, 2, 3 };
	
	public void setWidth(int width) {
		this.width = width;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	// Our vertex buffer.
	private FloatBuffer vertexBuffer;

	// Our index buffer.
	private ShortBuffer indexBuffer;
//	// Our vertex buffer.
//	private FloatBuffer vertexBuffer2;
//	
//	// Our index buffer.
//	private ShortBuffer indexBuffer2;
	
	protected void setVertices(float[] vertices) {
		this.vertices.clear();
        int len = 0 + 7*6;
        for (int i = 0, j = 0; i < len; i++, j++)
            tmpBuffer[j] = Float.floatToRawIntBits(vertices[i]);
        this.vertices.put(tmpBuffer, 0, 7*6);
        this.vertices.flip();
	}
	
	public Square() {

        this.hasColor = true;
        this.hasTexCoords = false;        
        this.vertexSize = (3 + (hasColor ? 4 : 0) + (hasTexCoords ? 2 : 0)) * 4;
        this.tmpBuffer = new int[6 * vertexSize / 4];

        ByteBuffer buffer = ByteBuffer.allocateDirect(6 * vertexSize);
        buffer.order(ByteOrder.nativeOrder());
        vertices = buffer.asIntBuffer();

        indices = null;
        setVertices(new float[] { -0.5f, -0.5f, -3, 1, 0, 0, 1,
                0.5f, -0.5f, -3, 1, 0, 0, 1,
                0.0f,  0.5f, -3, 1, 0, 0, 1,
                
                0.0f,  -0.5f, -5, 0, 1, 0, 1,
                1.0f,  -0.5f, -5, 0, 1, 0, 1,
                0.5f,  0.5f, -5, 0, 1, 0, 1});
//		// a float is 4 bytes, therefore we multiply the number if 
//		// vertices with 4.
//		ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
//		vbb.order(ByteOrder.nativeOrder());
//		vertexBuffer = vbb.asFloatBuffer();
//		vertexBuffer.put(vertices);
//		vertexBuffer.position(0);
		
		// short is 2 bytes, therefore we multiply the number if 
		// vertices with 2.
//		ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
//		ibb.order(ByteOrder.nativeOrder());
//		indexBuffer = ibb.asShortBuffer();
//		indexBuffer.put(indices);
//		indexBuffer.position(0);

//		// a float is 4 bytes, therefore we multiply the number if 
//		// vertices with 4.
//		ByteBuffer vbb2 = ByteBuffer.allocateDirect(vertices2.length * 4);
//		vbb2.order(ByteOrder.nativeOrder());
//		vertexBuffer2 = vbb2.asFloatBuffer();
//		vertexBuffer2.put(vertices2);
//		vertexBuffer2.position(0);
//		
//		// short is 2 bytes, therefore we multiply the number if 
//		// vertices with 2.
//		ByteBuffer ibb2 = ByteBuffer.allocateDirect(indices2.length * 2);
//		ibb2.order(ByteOrder.nativeOrder());
//		indexBuffer2 = ibb2.asShortBuffer();
//		indexBuffer2.put(indices2);
//		indexBuffer2.position(0);
	}
	
	/**
	 * This function draws our square on screen.
	 * @param gl
	 */
	public void draw(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT);            
	//    gl.glViewport(0, 0, glGraphics.getWidth(), glGraphics.getHeight());
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL10.GL_PROJECTION);
	    gl.glLoadIdentity();
	    gl.glOrthof(-1, 1, -1, 1, 10, -10);
	    gl.glMatrixMode(GL10.GL_MODELVIEW);
	    gl.glLoadIdentity();
	    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        vertices.position(0);
        gl.glVertexPointer(3, GL10.GL_FLOAT, vertexSize, vertices);

        if (hasColor) {
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
            vertices.position(3);
            gl.glColorPointer(4, GL10.GL_FLOAT, vertexSize, vertices);
        }

        if (hasTexCoords) {
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
            vertices.position(hasColor ? 7 : 3);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, vertexSize, vertices);
        }        
        if (indices != null) {
            indices.position(0);
            gl.glDrawElements(GL10.GL_TRIANGLES, 6,
                    GL10.GL_UNSIGNED_SHORT, indices);
        } else {
            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 6);
        }
        if (hasTexCoords)
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        if (hasColor)
            gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
	}
	
}
